import React, {memo, useEffect, useRef, useState} from "react";
import {SAMPLE_TASK, WELLS_COLUMN, WELLS_ROW} from "../../pages/main/plate/config";
import {useDispatch, useSelector} from "react-redux";

import "./index.css";
import {deepClone} from "../../common/utils";
import {saveData} from "../../pages/main/store/actionCreators";
import allSelectedPic from "./images/wellsBtn.png";

export default memo(function PlateTable(props) {
  const {wellsClickAction, plateClass, lineId, setWellId} = props;
  const wellsContainer = useRef();  //  Wells容器
  const {data, channels} = useSelector(state => ({
    data: state.dataReducer.data,
    channels: state.calculationReducer.channel
  }));
  const [wells, setWells] = useState(data.wells);  //  96个孔板对象
  const [showSelectBox, setShowSelectBox] = useState(false);  // 是否开启框选功能
  const [startX, setStartX] = useState(0);  //  鼠标按下起始位置横坐标
  const [startY, setStartY] = useState(0);  //  鼠标按下起始位置纵坐标
  const [selectBoxWidth, setSelectBoxWidth] = useState(0);  //  选择框宽度
  const [selectBoxHeight, setSelectBoxHeight] = useState(0);  //  选择框高度
  const [selectBoxLeft, setSelectBoxLeft] = useState(0);  //  选择框原点横坐标
  const [selectBoxTop, setSelectBoxTop] = useState(0);  //  选择框原点纵坐标
  const [leftMouseDown, setLeftMouseDown] = useState(false);  // 鼠标左键是否按下
  const [selectedWells, setSelectedWells] = useState([]); //  选中的Wells
  const dispatch = useDispatch();
  let cloneWells = [];
  let cloneSelectedWells = [];
  let wellWidth;
  let wellLeft;
  let plateBackground;
  switch (plateClass) {
    case "runPagePlateTableSmall":
      wellWidth = 33;
      wellLeft = 35;
      plateBackground = "plateTableBackgroundSmall";
      break;
    case "runPagePlateTableLarge":
      wellWidth = 50;
      wellLeft = 52;
      plateBackground = "plateTableBackgroundLarge";
      break;
    case "runPagePlateTableMid":
      wellWidth = 45;
      wellLeft = 47;
      plateBackground = "plateTableBackgroundMid";
      break;
    default:
      wellWidth = 40;
      wellLeft = 42;
      plateBackground = "plateTableBackground";
  }
  useEffect(() => {
    cloneWells = deepClone(wells, cloneWells);
    cloneWells.forEach(item => item.selected = false);
    setWells(cloneWells);
  }, []);

  useEffect(() => {
    cloneWells = deepClone(wells, cloneWells);
    cloneWells.forEach(well => well.selected = well.row * 12 + well.col === lineId);
    setWells(cloneWells);
    setWellId && setWellId([lineId]);
  }, [lineId]);

  useEffect(() => {
    let cloneDataWells = [];
    cloneDataWells = deepClone(data.wells, cloneDataWells);
    setWells(cloneDataWells.map(item => ({...item, selected: false})));
  }, [data]);

  //  鼠标移动后获取对应well的id
  function mouseEnter(indey) {
    cloneWells = deepClone(wells, cloneWells);
    cloneWells.forEach(well => well.selected = false);
    setWells(cloneWells);
    setWellId && setWellId([indey]);
  }

  //  选择一个well
  function selectSingleWells(e, well, indey) {
    cloneWells = deepClone(wells, cloneWells);
    (e.ctrlKey || e.shiftKey) || cloneWells.forEach((well, index) => indey === index || (well.show = false));
    cloneWells.forEach(well => well.selected = false);
    cloneWells[indey].show = !cloneWells[indey].show;
    setWells(cloneWells);
    dispatch(saveData({...data, wells: cloneWells}));
    wellsClickAction && wellsClickAction(indey);
    setWellId && setWellId([indey]);
  }

  //  鼠标左键按下监听器
  function mouseDownListener(e) {
    if (e.buttons !== 1) {      //  判断鼠标左键按下
      return;
    }
    e.preventDefault();
    if (e.ctrlKey) {  //  按下ctrl
      wells.forEach((well, index) => well.show && cloneSelectedWells.push(index));
      setSelectedWells([...new Set(cloneSelectedWells)]); //  记录先前选中的wells
    } else if (e.shiftKey) {  //  按下shift
      wells.forEach((well, index) => well.show && cloneSelectedWells.push(index));
      setSelectedWells([...new Set(cloneSelectedWells)]); //  记录先前选中的wells
      setLeftMouseDown(true);
      setStartX(e.clientX - wellsContainer.current.offsetLeft); //  设置原点坐标为容器左上角
      setStartY(e.clientY - wellsContainer.current.offsetTop);
    } else {  //  不按ctrl和shift
      setSelectedWells([]);
      setLeftMouseDown(true);
      setStartX(e.clientX - wellsContainer.current.offsetLeft); //  设置原点坐标为容器左上角
      setStartY(e.clientY - wellsContainer.current.offsetTop);
    }
  }

  //  鼠标移动监听器
  function mouseMoveListener(e) {
    if (!leftMouseDown) {
      return;
    }
    e.preventDefault();
    let {left, top} = wellsContainer.current.getBoundingClientRect(); //  容器上边(左边)到视窗上边(左边)的距离
    let [nowX, nowY] = [e.clientX - left, e.clientY - top]; //  鼠标当前的位置
    setSelectBoxLeft(Math.min(nowX, startX));
    setSelectBoxTop(Math.min(nowY, startY));
    setSelectBoxWidth(Math.abs(nowX - startX));
    setSelectBoxHeight(Math.abs(nowY - startY));
    setShowSelectBox(true);
    if (selectBoxWidth > 10 && selectBoxHeight > 10) {
      cloneWells = deepClone(wells, cloneWells);
      cloneWells.forEach(well => well.selected = well.show = (wellWidth + well.col * wellLeft) > selectBoxLeft
        && (wellWidth + well.row * wellLeft) > selectBoxTop
        && well.col * wellLeft < selectBoxLeft + selectBoxWidth
        && well.row * wellLeft < selectBoxTop + selectBoxHeight);
      (e.ctrlKey || e.shiftKey) && selectedWells.forEach(well => cloneWells[well].selected = cloneWells[well].show = true);  //  将先前选中的wells重新设置为true
      setWells(cloneWells);
    }
  }

  //  鼠标左键抬起监听器
  function mouseUpListener() {
    if (!leftMouseDown) {
      return;
    }
    cloneWells = deepClone(wells, cloneWells);
    cloneWells.forEach(well => {  //  鼠标抬起后改变Show的状态,selected变为true,selected只是用来判断框选了哪些well
      if (well.selected) {
        //  TODO:
        // well.show = !well.show;
        well.selected = false;
      }
    });
    setWells(cloneWells);
    dispatch(saveData({...data, wells: cloneWells}));
    setShowSelectBox(false);
    setLeftMouseDown(false);
  }

  //  鼠标移出wells面板监听器
  function mouseLeaveListener() {
    if (!leftMouseDown) {
      return;
    }
    setShowSelectBox(false);
    setLeftMouseDown(false);
  }

  //  选择整行列的wells
  function selectRowOrCol(e, indey, type) {
    cloneWells = deepClone(wells, cloneWells);
    let selectedWells = cloneWells.filter(well => well[type] === indey && well.show),
      count = selectedWells.length;
    if ((type === "row" && count === 12) || (type === "col" && count === 8)) {  //  如果全选则取消全选
      cloneWells.forEach(well => well[type] === indey && (well.show = false));
      selectedWells.forEach(wells => wells.show = false);
      setWells(cloneWells);
      dispatch(saveData({...data, wells: cloneWells}));
      return;
    }
    cloneWells.forEach(well => well[type] === indey && (well.show = true));
    setWells(cloneWells);
    dispatch(saveData({...data, wells: cloneWells}));
  }

  //  选择全部
  function selectAll() {
    cloneWells = deepClone(wells, cloneWells);
    if (wells.some(item => !item.show)) {
      cloneWells.forEach(well => well.show = true);
    } else {
      cloneWells.forEach(well => well.show = false);
    }
    setWells(cloneWells);
    dispatch(saveData({...data, wells: cloneWells}));
  }

  return (
    <section className={plateClass || "runPagePlateTable"}
             onMouseLeave={mouseLeaveListener}
    >
      <div>
        <div onClick={selectAll}
             style={{backgroundImage: `url(${allSelectedPic})`}}/>
        <div>
          {
            WELLS_COLUMN.map((col, index) => <div key={col} onClick={e => selectRowOrCol(e, index, "col")}>{col}</div>)
          }
        </div>
      </div>
      <div>
        {
          WELLS_ROW.map((row, index) => <div key={row} onClick={e => selectRowOrCol(e, index, "row")}>{row}</div>)
        }
      </div>
      <div ref={wellsContainer}
           onMouseDown={e => mouseDownListener(e)}
           onMouseMove={e => mouseMoveListener(e)}
           onMouseUp={mouseUpListener}
      >
        {
          wells.map((well, index) => (
            <div key={well.row * 12 + well.col}
                 style={
                   {
                     borderColor: well.selected ? "#fff" : `${SAMPLE_TASK[well.type]}`,
                     backgroundColor: well.show ? `${well.groupColor || "#9E9E9E"}` : null
                   }
                 }
                 onClick={e => selectSingleWells(e, well, index)}
            >
              <div style={well.sampleName ? {backgroundColor: `${well.sampleColor}`} : null}>{well.sampleName}</div>
              <ul>
                {
                  well.targets.map(target => (
                    <li key={target.name} style={{backgroundColor: target.color}}/>
                  ))
                }
              </ul>
              {
                (well.groupColor && well.show)
                  ? <div style={{backgroundColor: `${well.groupColor}`}} className={plateBackground}/>
                  : null
              }
            </div>
          ))
        }
        {
          showSelectBox
            ? <div className="platePageSelectBox" style={{left: `${selectBoxLeft}px`, top: `${selectBoxTop}px`, width: `${selectBoxWidth}px`, height: `${selectBoxHeight}px`}}/>
            : null
        }
      </div>
    </section>
  );
});
